<template>
	<view class="diary-container">
		<view class="diary-content">
			<tmt-calendar background="#ffffff" actionColor="black" backColor="black" backBg="#ffffff" selectBg="#99BBFF"
				weekColor="black" dayColor="black" unfoldBtnColor="black" :defaultDate="currentDate"
				:point-list="diaryDates" :show="true" :theme-color="themeColor" @changeDate="changeDate">
			</tmt-calendar>
			<view class="diary-form">
				<textarea v-model="DiaryForm.content"
					:disabled="selectedDate.value!== currentDate.value  || isSubmitDisabled" placeholder="请输入今日学习心得..."
					class="diary-input" :class="{ 'diary-input-disabled': selectedDate.value!== currentDate.value }" />
				<!-- 上传文件回显区域 -->
				<view class="file-preview" v-if="uploadedImageFiles.length > 0">
					<view v-for="(image, index) in uploadedImageFiles" :key="index" class="file-item"
						@click="handleDeleteImageFile(index,image)">
						<image :src="image.url" mode="aspectFit"></image>
					</view>
				</view>
				<view class="file-preview" v-if="uploadedFiles.length > 0">
					<view v-for="(file, index) in uploadedFiles" :key="index" class="file-item"
						@click="handleDeleteFile(index,file)">
						<image class="file-icon" src="/static/FileIcon.png"></image>
						<text>{{file.fileName}}</text>
					</view>
				</view>
			</view>
			<button class="submit-btn" @tap="handleUploadClick" :disabled="isSubmitDisabled"
				:class="{'submit-btn-enabled':!isSubmitDisabled, 'submit-btn-disabled': isSubmitDisabled}">
				上传文件
			</button>
			<xe-upload ref="xeUploadRef" :options="uploadOptions" @callback="handleUploadCallback"></xe-upload>
			<button class="submit-btn" :class="{ 'submit-btn-disabled': isSubmitDisabled }" @tap="submitDiary"
				:disabled="isSubmitDisabled">
				{{ submitButtonText }}
			</button>
		</view>
		<view class="teacher-feedback" v-if="DiaryForm.state != null && DiaryForm.state === 1">
			<view class="feedback-header">
				<uni-icons type="checkmarkempty" size="20" color="#99BBFF"></uni-icons>
				<text class="feedback-title">教师批阅</text>
			</view>
			<view class="feedback-divider"></view>
			<view class="feedback-body">
				<view class="feedback-item">
					<text class="feedback-label">评语：</text>
					<text class="feedback-content">{{ DiaryForm.advice || '暂无评语' }}</text>
				</view>
				<view class="feedback-item">
					<text class="feedback-label">得分：</text>
					<text class="feedback-score">{{ DiaryForm.score || 0 }}</text>
				</view>
				<view class="feedback-item">
					<text class="feedback-label">批阅时间：</text>
					<text class="feedback-date">{{ formatDate(DiaryForm.confirmDate) }}</text>
				</view>
			</view>
		</view>
	</view>
</template>


<script setup>
	import {
		ref,
		reactive,
		computed,
		onMounted
	} from 'vue';
	import {
		apiDairyLog,
		apiGetDateLog,
		apiDeleteDiaryFiles,
		apiUploadDiaryFile
	} from '../../api/apis';
	import {
		onLoad
	} from '@dcloudio/uni-app';
	// Constants
	const themeColor = '#FFA46F';

	// Reactive state
	const currentDate = ref('');
	const selectedDate = ref('');
	const diaryDates = ref([]);
	const isLoading = ref(false);
	// 上传的文件数组
	const uploadedFiles = ref([]);
	// 上传的图片数组
	const uploadedImageFiles = ref([]);
	const DiaryForm = reactive({
		content: '',
		userId: null,
		projectId: null,
		advice: "",
		confirmDate: null,
		state: null,
		score: null,
	});

	const InsertDiaryForm = reactive({
		content: '',
		userId: null,
		projectId: null,
		date: null
	});

	const getDateLogForm = reactive({
		date: null,
		userId: null,
		projectId: null,
	});
	const token = ref("");

	// Computed properties
	const isSubmitDisabled = computed(() => {
		return DiaryForm.state === 1;
	});

	const submitButtonText = computed(() => {
		if (isLoading.value) return '提交中...';
		if (DiaryForm.state === 1) return '已提交';
		return '提交';
	});

	const deleteFileForm = reactive({
		projectId: null,
		userId: null,
		fileName: '',
		date: ''
	})

	// 定义响应式数据
	const uploadOptions = ref({});
	// 引用组件
	const xeUploadRef = ref(null);

	// 处理上传点击事件，这里先从手机读取文件到软件本地
	const handleUploadClick = () => {
		if (currentDate.value != selectedDate.value) {
			uni.showToast({
				title: '只能上传当天的文件',
				icon: "none"
			})
			return
		}
		xeUploadRef.value.upload('file', {});
	};

	// Lifecycle
	onMounted(async () => {
		try {
			initializeDate();
			await loadUserInfo();
			await handleGetDateLog();
		} catch (error) {
			console.error('初始化失败:', error);
		}
	});

	const loadUserInfo = () => {
		return new Promise((resolve, reject) => {
			uni.getStorage({
				key: 'studentInfo',
				success: ({
					data: studentVO
				}) => {
					const {
						id,
						project
					} = studentVO;
					DiaryForm.userId = id;
					DiaryForm.projectId = project.id;
					getDateLogForm.userId = id;
					getDateLogForm.projectId = project.id;
					InsertDiaryForm.userId = id;
					InsertDiaryForm.projectId = project.id;
					deleteFileForm.userId = id;
					deleteFileForm.projectId = project.id;
					resolve();
				},
				fail: (error) => {
					uni.showToast({
						title: '获取用户信息失败',
						icon: 'none'
					});
					reject(error);
				}
			});
		});
	};


	const initializeDate = () => {
		const date = new Date();
		const year = date.getFullYear();
		const month = String(date.getMonth() + 1).padStart(2, '0');
		const day = String(date.getDate()).padStart(2, '0');
		const formattedDate = `${year}-${month}-${day}`;
		currentDate.value = formattedDate;
		selectedDate.value = formattedDate;
	};



	const handleGetDateLog = async (showToastOnError = true) => {
		try {
			getDateLogForm.date = selectedDate.value;
			const res = await apiGetDateLog(getDateLogForm);
			console.log(res.data)
			if (res.code === 0 && res.data) {
				const {
					content,
					advice,
					score,
					confirmDate,
					state
				} = res.data;
				DiaryForm.content = content;
				DiaryForm.advice = advice;
				DiaryForm.score = score;
				DiaryForm.confirmDate = confirmDate;
				DiaryForm.state = state;
				uploadedFiles.value = [];
				uploadedImageFiles.value = [];
				for (let i = 0; i < res.data.fileNames.length; i++) {
					uploadedFiles.value.push(handleUrlFile({
						fileName: res.data.fileNames[i],
						primevalName: res.data.fileNames[i],
						status: 'success',
						localUrl: ''
					}));
				}
				for (let i = 0; i < res.data.imageUrls.length; i++) {
					const imageUrl = res.data.imageUrls[i];
					const cachedImagePath = uni.getStorageSync(`image_${imageUrl}`);
					if (cachedImagePath) {
						// 如果本地缓存中有图片，直接使用缓存
						uploadedImageFiles.value.push({
							url: cachedImagePath, // 本地缓存地址
							netUrl: imageUrl,
							status: 'loadFromLocal' // 状态
						});
					} else {
						// 如果本地缓存中没有图片，从服务器获取
						uploadedImageFiles.value.push({
							url: imageUrl, // 本地预览地址
							netUrl: imageUrl,
							status: 'loading' // 状态
						});
					}
				}
				// 只有在获取到对应日期的日志数据时才添加到列表中
				if (!diaryDates.value.includes(selectedDate.value)) {
					diaryDates.value.push(selectedDate.value);
				}
			} else {
				resetDiaryForm();
				uploadedFiles.value = [];
				uploadedImageFiles.value = [];
			}
		} catch (error) {
			uploadedFiles.value = [];
			uploadedImageFiles.value = [];
			console.error('获取日志失败:', error);
			if (showToastOnError) {
				uni.showToast({
					title: '没有填写日志',
					icon: 'none'
				});
			}
		}
	};


	// 处理上传回调事件
	var uploadnum = 0; // 上传的文件数
	var successNum = 0; // 成功的文件数
	var failNum = 0; // 失败的文件数

	const handleUploadCallback = async (e) => {
		uni.showLoading({
			title: '正在上传…'
		});
		successNum = 0; // 成功的文件数
		failNum = 0; // 失败的文件数
		if (e.type == 'success' || e.type == 'choose') {
			console.log(e);
			uploadnum = e.data.length;
			e.data.forEach(data => {
				if (data.fileType === "image") {
					const image = {
						url: data.tempFilePath, // 本地预览地址
						status: 'loadFromLocal' // 状态
					};
					uploadedImageFiles.value.push(image);
					uploadImage(image)
				} else {
					let file = {
						fileName: data.name,
						primevalName: '',
						localUrl: data.tempFilePath,
						status: 'loading'
					}
					uploadedFiles.value.push(file);
					console.log(file.fileName, file.localUrl)
					uploadFile(file);
				}

			})
			// 只有在获取到对应日期的日志数据时才添加到列表中
			if (!diaryDates.value.includes(selectedDate.value)) {
				diaryDates.value.push(selectedDate.value);
			}
		} else if (e.type == 'warning') {
			console.log("选择文件失败")
			uni.hideLoading();
			uni.showToast({
				title: '标题',
				icon: 'error'
			});
		}
	};


	// 向网络发送图片的请求
	const uploadImage = async (image) => {
		try {
			getDateLogForm.date = selectedDate.value;
			console.log(image.url)
			console.log(getDateLogForm);
			const response = await apiUploadDiaryFile({
				filePath: image.url,
				date: getDateLogForm.date,
				userId: Number(getDateLogForm.userId),
				projectId: Number(getDateLogForm.projectId)
			});

			// 上传成功后的逻辑
			image.status = 'success';
			image.netUrl = response;
			const index = uploadedImageFiles.value.findIndex(img => img.url === image.url);
			if (index !== -1) {
				uploadedImageFiles.value[index] = {
					...image
				};
				cacheImage(response); // 缓存图片
			}
			console.log("图片上传成功");
			successNum++;
		} catch (error) {
			console.error('图片上传失败:', error);
			const index = uploadedImageFiles.value.findIndex(img => img.url === image.url);
			if (index !== -1) {
				uploadedImageFiles.value.splice(index, 1);
			}
			failNum++;
		} finally {
			uploadnum--;
			allUploaded();
		}
	};


	// 向网络发送文件的请求
	const uploadFile = async (file) => {
		try {
			getDateLogForm.date = selectedDate.value;
			console.log(getDateLogForm);
			const response = await apiUploadDiaryFile({
				filePath: file.localUrl,
				date: getDateLogForm.date,
				userId: Number(getDateLogForm.userId),
				projectId: Number(getDateLogForm.projectId)
			});

			// 上传成功后的逻辑
			file.status = 'success';
			file.primevalName = response;
			const index = uploadedFiles.value.findIndex(filei => filei.localUrl === file.localUrl);
			if (index !== -1) {
				uploadedFiles.value[index] = {
					...file
				};
			}
			successNum++;
		} catch (error) {
			console.error('文件上传失败:', error);
			const index = uploadedFiles.value.findIndex(filei => filei.localUrl === file.localUrl);
			if (index !== -1) {
				uploadedFiles.value.splice(index, 1);
			}
			failNum++;
		} finally {
			uploadnum--;
			allUploaded();
		}
	};


	// 将图片缓存到本地
	const cacheImage = (imageUrl) => {
		// 将保存的文件路径缓存到本地存储
		const cacheKey = `image_${imageUrl}`; // 使用 imageUrl 作为缓存键
		if (uni.getStorageSync(cacheKey)) return; // 已缓存则跳过
		// 先下载图片到本地临时文件
		uni.downloadFile({
			url: imageUrl, // 网络图片路径
			success: (downloadRes) => {
				if (downloadRes.statusCode === 200) {
					const tempFilePath = downloadRes.tempFilePath; // 获取临时文件路径

					// 将临时文件保存到本地
					uni.saveFile({
						tempFilePath: tempFilePath,
						success: (saveRes) => {
							const savedFilePath = saveRes.savedFilePath; // 获取保存后的文件路径
							uni.setStorageSync(cacheKey, savedFilePath);

							console.log('图片缓存成功:', savedFilePath);
						},
						fail: (err) => {
							console.error('保存图片失败:', err);
						}
					});
				} else {
					console.error('下载图片失败，状态码:', downloadRes.statusCode);
				}
			},
			fail: (err) => {
				console.error('下载图片失败:', err);
			}
		});
	};

	const allUploaded = () => {
		if (uploadnum === 0) {
			uni.hideLoading();
			if (successNum === 0) {
				uni.showToast({
					title: '上传失败',
					icon: 'error'
				});
			} else {
				if (failNum === 0) {
					uni.showToast({
						title: '上传成功',
						icon: 'success'
					});
				} else {
					uni.showToast({
						title: successNum + '个成功，' + failNum + '个失败',
						icon: 'none'
					});
				}
			}
		}
	}

	// Methods
	const formatDate = (date) => {
		if (!date) return '暂无';
		return new Date(date).toLocaleString('zh-CN', {
			year: 'numeric',
			month: '2-digit',
			day: '2-digit',
			hour: '2-digit',
			minute: '2-digit'
		});
	};

	const formatDisplayDate = (date) => {
		if (!date) return '';
		const d = new Date(date);
		return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日`;
	};



	// 对文件的名称进行处理，删去uuid
	const handleUrlFile = (file) => {
		try {

			let fileName = file.fileName.substring(file.fileName.lastIndexOf('/') + 1);

			// 使用正则表达式去除 UUID（假设是标准格式）和时间戳（假设是以 "-" 分隔的纯数字）
			fileName = fileName.replace(/^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}_/, '') // 去掉 UUID 和前面的下划线
				.replace(/-\d+\./, '.'); // 去掉时间戳（保留文件后缀）

			console.log(fileName);
			file.fileName = fileName;
			return file;
		} catch (error) {
			console.error('无效的 URL:', error);
			return null;
		}
	}

	const resetDiaryForm = () => {
		Object.assign(DiaryForm, {
			content: '',
			advice: '',
			confirmDate: null,
			state: null,
			score: null
		});
	};

	const goBack = () => {
		uni.navigateBack();
	};

	const changeDate = async ({
		year,
		month,
		day
	}) => {
		const newDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
		selectedDate.value = newDate;
		// 先重置日志表单数据，避免之前数据干扰
		resetDiaryForm();
		// 调用接口获取对应日期日志数据
		await handleGetDateLog();
	};

	function getZeroTime(date) {
		const d = new Date(date);
		d.setHours(0, 0, 0, 0); // 设置时间为 00:00:00
		return d.getTime();
	}
	const submitDiary = async () => {
		if (isSubmitDisabled.value) return;
		const now = getZeroTime(new Date()); // 当前日期的零点时间戳
		const endDate = getZeroTime(new Date(selectedDate.value)); // 选中日期的零点时间戳
		if (now != endDate) {
			uni.showToast({
				title: "只能填写当天日志",
				icon: 'none',
				duration: 1000,
			});
			return;
		}
		if (DiaryForm.content == null || DiaryForm.content.trim() == "") {
			uni.showToast({
				title: "日志内容不能为空",
				icon: 'none',
				duration: 1000,
			});
			return;
		}
		try {
			isLoading.value = true;
			InsertDiaryForm.date = selectedDate.value;
			InsertDiaryForm.content = DiaryForm.content;

			const res = await apiDairyLog(InsertDiaryForm);

			if (res.code === 0) {
				uni.showToast({
					title: res.msg || '提交成功',
					icon: 'success'
				});
				// 提交成功后，将对应日期添加到有日志的日期列表中
				if (!diaryDates.value.includes(selectedDate.value)) {
					diaryDates.value.push(selectedDate.value);
				}
				await handleGetDateLog()
			} else {
				throw new Error(res.msg || '提交失败');
			}
		} catch (error) {
			uni.showToast({
				title: error.message || '提交失败',
				icon: 'none'
			});
		} finally {
			isLoading.value = false;
		}
	};

	// 删除图片的方法
	const handleDeleteImageFile = (index, image) => {
		if (isSubmitDisabled.value) return;
		uni.showModal({
			title: '确认删除',
			content: '是否确认删除这个图片？',
			success: async (res) => {
				if (res.confirm) {
					deleteFileForm.fileName = image.netUrl;
					deleteFileForm.date = selectedDate.value;
					// 显示删除的加载框
					uni.showLoading({
						title: '正在删除…'
					});
					try {
						let modelRes = await apiDeleteDiaryFiles(deleteFileForm);
						console.log(modelRes.code)
						if (modelRes.code === 200) {
							uploadedImageFiles.value.splice(index, 1);
							// 2. 删除本地缓存
							const cacheKey = `image_${image.netUrl}`;
							uni.removeStorageSync(cacheKey);

							uni.hideLoading();
							uni.showToast({
								title: '删除成功',
								icon: 'success'
							});
						} else {
							uni.hideLoading();
							uni.showToast({
								title: '删除失败',
								icon: 'error'
							});
						}
						console.log(modelRes)
					} catch (error) {
						uni.hideLoading();
						console.error('删除图片时发生错误:', error);
						uni.showToast({
							title: '删除失败',
							icon: 'error'
						});
					}
				}
			}
		});
	};

	// 删除文件的方法
	const handleDeleteFile = (index, file) => {
		if (isSubmitDisabled.value) return;
		uni.showModal({
			title: '确认删除',
			content: '是否确认删除这个文件？',
			success: async (res) => {
				if (res.confirm) {
					// 弹出删除图片的提示
					uni.showLoading({
						title: '正在删除…'
					});
					deleteFileForm.fileName = file.primevalName;
					deleteFileForm.date = selectedDate.value;
					console.log(deleteFileForm.fileName);
					try {
						let modelRes = await apiDeleteDiaryFiles(deleteFileForm);
						console.log(typeof modelRes);
						if (modelRes.code === 200) {
							uploadedFiles.value.splice(index, 1);
							uni.hideLoading();
							uni.showToast({
								title: '删除成功',
								icon: 'success'
							});

						} else {
							uni.hideLoading();
							uni.showToast({
								title: '删除失败',
								icon: 'error'
							});
						}
						console.log(modelRes);
					} catch (error) {
						uni.hideLoading();
						console.error('删除文件时发生错误:', error);
						uni.showToast({
							title: '删除失败',
							icon: 'error'
						});
					}
				}
			}
		});
	};
</script>

<style lang="scss">
	.diary-container {
		min-height: 100vh;
		padding: 0;
		padding-top: var(--status-bar-height, 44px);
	}

	.diary-header {
		padding: 20rpx 30rpx;

		.header-content {
			position: relative;
			display: flex;
			align-items: center;
			justify-content: space-between;
			height: 88rpx;

			.back-icon {
				position: absolute;
				left: 0;
				display: flex;
				align-items: center;
				height: 100%;
				padding: 0 20rpx;
			}

			.title {
				flex: 1;
				text-align: center;
				font-size: 36rpx;
				font-weight: 600;
				color: #333;
			}
		}
	}


	.diary-content {
		padding: 0rpx 20rpx 20rpx 20rpx;
	}

	.diary-input {
		background-color: #FFFFFF;
		padding: 20rpx;
		width: 94%;
		height: 300rpx;
		margin: 20rpx 0;
		border-radius: 35rpx;
		border: 1rpx solid;
		font-size: 28rpx;
		transition: all 0.3s ease;
	}

	.diary-input:focus {
		border-color: #FFA46F;
		box-shadow: 0 0 0 2px rgba(255, 164, 111, 0.1);
	}

	.diary-input-disabled {
		background-color: #F7FAFC;
		color: #718096;
	}

	.submit-btn {
		margin-top: 20rpx;
		background: #99BBFF;
		width: 100%;
		height: 88rpx;
		border-radius: 35rpx;
		font-size: 32rpx;
	}

	.submit-btn:active {
		transform: scale(0.98);
		opacity: 0.9;
	}

	.submit-btn-disabled {
		background-color: #e0e0e0;
		color: #999;
	}

	.teacher-feedback {
	
		margin: 0 20rpx;
		background: #ffffff;
		padding: 30rpx;
		border-radius: 24rpx;
		box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06); // 增强阴影层次
		transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); // 添加过渡动画
		border: 2rpx solid rgba(241, 245, 249, 0.6); // 添加细边框
	}

	.feedback-header {
		display: flex;
		align-items: center;
		gap: 10rpx;
	}

	.feedback-title {
		font-size: 32rpx;
		font-weight: 600;
		color: #2D3748;
	}

	.feedback-divider {
		height: 1px;
		background-color: #E2E8F0;
		margin: 20rpx 0;
	}

	.feedback-body {
		display: flex;
		flex-direction: column;
		gap: 16rpx;
	}

	.feedback-item {
		display: flex;
		align-items: flex-start;
		gap: 10rpx;
	}

	.feedback-label {
		font-size: 28rpx;
		color: #718096;
		min-width: 140rpx;
	}

	.feedback-content {
		flex: 1;
		font-size: 28rpx;
		color: #2D3748;
		line-height: 1.6;
	}

	.feedback-score {
		color: #FFA46F;
		font-weight: 600;
		font-size: 32rpx;
	}

	.feedback-date {
		font-size: 26rpx;
		color: #718096;
	}

	.file-preview {
		margin-top: 20rpx;
	}

	.file-item {
		display: flex;
		align-items: center;
		padding: 20rpx;
		background: #ffffff;
		border: 1rpx solid #f0f0f0;
		border-radius: 16rpx;
		margin-bottom: 20rpx;
		position: relative;
		overflow: hidden;
		transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);

	}

	.file-icon {
		width: 40px;
		/* 固定宽度 */
		height: 40px;
		/* 固定高度 */
		margin-right: 10px;
		/* 与文字之间的间隔 */
		flex-shrink: 0;
		/* 防止被压缩 */
	}
</style>